package com.jay.demo.proxy;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

public class ServerInboundHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(ServerInboundHandler.class);

    private NettyHttpClient client;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

//        if(msg instanceof  LastHttpContent){
//            DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
//                Unpooled.wrappedBuffer("hello world".getBytes()));
//            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
//            ctx.writeAndFlush(response);
//        }
        if(msg instanceof HttpRequest){
            client = HttpClientPool.borrow();
            logger.info("borrow success");
            client.connect("127.0.0.1", 8080);
            client.pushChannel(ctx.channel());

            for(Map.Entry entry : ((HttpRequest) msg).headers().entries()){
                logger.info("{}: {}", entry.getKey(), entry.getValue());
            }
        }
        client.write(msg);
        if(msg instanceof LastHttpContent){
            client.flush();
            HttpClientPool.giveBack(client);
            logger.info("flush success");
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
        logger.error("{}: {}", cause.getClass().getName(), cause.getMessage());
        ctx.close();
    }
}
